/**
 * @author : cyb1010
 * @date   : 2024-06-11 09:04:56
 * @file   : edge.cpp
 */
#include <bits/stdc++.h>
using namespace std;
#define fo(s) freopen(s ".in", "r", stdin), freopen(s ".out", "w", stdout)
#define fi first
#define se second
#define ALL(v) (v).begin(), (v).end()
#define SZ(v) int(v.size())
typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
void ckmx(int &x, int y) { x < y && (x = y); }
void ckmn(int &x, int y) { x > y && (x = y); }
bool ed;
const int N = 150010;
int __, n, m, a, b, id[N], rk[N];
ll dis[N];
vector<int> g[N], s[N], ts[N];
bitset<N> bs[20000];
bool st;
int main() {
    fo("edge8");
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m >> a >> b;
    for (int x, y; m--;) {
        cin >> x >> y;
        g[x].push_back(y), g[y].push_back(x);
        s[x].push_back(y), s[y].push_back(x);
    }
    iota(id, id + n, 1);
    sort(id, id + n, [&](int x, int y) { return g[x].size() < g[y].size(); });
    for (int i = 0; i < n; i++) {
        rk[id[i]] = i;
        if (i < 20000) {
            for (int j : g[id[i]]) bs[i].set(j);
        } else
            sort(g[id[i]].begin(), g[id[i]].end());
    }
    queue<pair<int, ll>> A, B;
    // memset(dis, 0x7f, sizeof(dis));
    fill(dis + 1, dis + 1 + n, (ll)5e17);
    A.emplace(1, dis[1] = 0);
    while (!A.empty() || !B.empty()) {
        auto front = [&] {
            if (B.empty()) {
                auto x = A.front();
                return A.pop(), x;
            }
            if (A.empty() || A.front().se > B.front().se) {
                auto x = B.front();
                return B.pop(), x;
            }
            auto x = A.front();
            return A.pop(), x;
        };
        auto [x, d] = front();
        if (d != dis[x]) continue;
        int cnt = 0;
        for (int i : g[x]) {
            if (dis[i] > d + a) A.emplace(i, dis[i] = d + a);
            vector<int> rem;
            cnt += s[i].size();
            auto cont = [&](int t) {
                if (rk[x] < 20000) return bs[rk[x]].test(t);
                auto p = lower_bound(g[x].begin(), g[x].end(), t);
                return p != g[x].end() && *p == t;
            };
            for (int j : s[i]) {
                if (cont(j)) {
                    rem.push_back(j);
                    continue;
                }
                if (dis[j] > d + b) B.emplace(j, dis[j] = d + b);
            }
            s[i].swap(rem);
        }
    }
    for (int i = 2; i <= n; i++) cout << dis[i] << '\n';
    cerr << clock() << endl;
    return 0 ^ __ ^ 0;
}